﻿using Core;
using Core.Data;
using Core.Domain.Catalog;
using Core.Domain.Stores;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Services.Catelog
{
    /// <summary>
    /// 类别服务实现类
    /// </summary>
    public partial class CategoryService : ICategoryService
    {
        #region Fields

        private readonly IRepository<Category> _categoryRepository;
        private readonly IRepository<StoreMapping> _storeMappingRepository;
        private readonly IWorkContext _workContext;
        private readonly IStoreContext _storeContext;

        #endregion

        #region Ctor

        /// <summary>
        /// Ctor
        /// </summary>
        public CategoryService(IRepository<Category> categoryRepository,
            IRepository<StoreMapping> storeMappingRepository,
            IWorkContext workContext,
            IStoreContext storeContext)
        {
            this._categoryRepository = categoryRepository;
            this._storeMappingRepository = storeMappingRepository;
            this._workContext = workContext;
            this._storeContext = storeContext;
        }

        #endregion

        #region Methods

        /// <summary>
        /// 删除类别
        /// </summary>
        public virtual void DeleteCategory(Category category)
        {
            if (category == null)
                throw new ArgumentNullException("category");

            category.Deleted = true;
            UpdateCategory(category);

            var subcategories = GetAllCategoriesByParentCategoryId(category.Id);
            foreach (var subcategory in subcategories)
            {
                subcategory.ParentId = 0;
                UpdateCategory(subcategory);
            }
        }

        /// <summary>
        /// 获取所有类别
        /// </summary>
        public virtual IPagedList<Category> GetAllCategories(string categoryName = "",
            int pageIndex = 0, int pageSize = int.MaxValue)
        {
            var query = _categoryRepository.Table;
            if (!String.IsNullOrWhiteSpace(categoryName))
                query = query.Where(c => c.Name.Contains(categoryName));
            query = query.Where(c => !c.Deleted);
            query = query.OrderBy(c => c.ParentId).ThenBy(c => c.DisplayOrder);

            query = from c in query
                    group c by c.Id
                        into cGroup
                        orderby cGroup.Key
                        select cGroup.FirstOrDefault();
            query = query.OrderBy(c => c.ParentId).ThenBy(c => c.DisplayOrder);

            var unsortedCategories = query.ToList();

            //排序
            var sortedCategories = unsortedCategories.SortCategoriesForTree();

            return new PagedList<Category>(sortedCategories, pageIndex, pageSize);
        }

        /// <summary>
        /// 根据父Id获取类别集合
        /// </summary>
        public virtual IList<Category> GetAllCategoriesByParentCategoryId(int ParentId)
        {
            var query = _categoryRepository.Table;
            query = query.Where(c => c.ParentId == ParentId);
            query = query.Where(c => !c.Deleted);
            query = query.OrderBy(c => c.DisplayOrder);

            query = from c in query
                    group c by c.Id
                        into cGroup
                        orderby cGroup.Key
                        select cGroup.FirstOrDefault();
            query = query.OrderBy(c => c.DisplayOrder);

            return query.ToList();
        }


        /// <summary>
        /// 根据主键获取类别
        /// </summary>
        public virtual Category GetCategoryById(int categoryId)
        {
            if (categoryId == 0)
                return null;
            return _categoryRepository.GetById(categoryId);
        }

        /// <summary>
        /// 新增类别
        /// </summary>
        /// <param name="category">Category</param>
        public virtual void InsertCategory(Category category)
        {
            if (category == null)
                throw new ArgumentNullException("category");

            _categoryRepository.Insert(category);

        }

        /// <summary>
        /// Updates the category
        /// </summary>
        /// <param name="category">Category</param>
        public virtual void UpdateCategory(Category category)
        {
            if (category == null)
                throw new ArgumentNullException("category");

            //validate category hierarchy
            var parentCategory = GetCategoryById(category.ParentId);
            while (parentCategory != null)
            {
                if (category.Id == parentCategory.Id)
                {
                    category.ParentId = 0;
                    break;
                }
                parentCategory = GetCategoryById(parentCategory.ParentId);
            }

            _categoryRepository.Update(category);
        }



        #endregion
    }
}
